package com.qf.service.impl;

import com.qf.service.ICacheService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Service
public class CacheServiceImpl implements ICacheService {

    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void save2Cache(String key, Object value, Long expireSecond) {
//        key 和value  都不能为空       有效时间不能为负数
        if(StringUtils.isEmpty(key)|| StringUtils.isEmpty(value)||expireSecond==null||expireSecond<=0){
            //跑出异常,或者是返回特定数据
            return;
        }
//                                                              以秒为单位
        redisTemplate.opsForValue().set(key,value,expireSecond, TimeUnit.SECONDS);
    }

    @Override
    public void save2Cache(String key, String value) {
        if(StringUtils.isEmpty(key)|| StringUtils.isEmpty(value)){
            return;
        }
        redisTemplate.opsForSet().remove(key, value);

    }

    @Override
    public Object get(String key) {
//        传递了空的key
        if(StringUtils.isEmpty(key)){
            return null;
        }
        return redisTemplate.opsForValue().get(key);
    }

//    @Override
//    public String getp(String key) {
//        //        传递了空的key
//        if(StringUtils.isEmpty(key)){
//            return null;
//        }
//        return redisTemplate.opsForValue().get(key);
//    }

    @Override
    public boolean delete(String  keys) {
        if(keys==null){
            return false;
        }

        return redisTemplate.delete(keys);
    }

    @Override
    public Boolean expire(String key, Integer expireSecond) {
        if(StringUtils.isEmpty(key)||expireSecond<=0||expireSecond==null){
            return false;
        }
//        设置有效时间
        return redisTemplate.expire(key, expireSecond, TimeUnit.SECONDS);
    }

    @Override
    public long incr(String key, long delta) {

        if(StringUtils.isEmpty(key)||delta==0){
            //这个返回值我们需要认真考虑下,因为你返回任何数据都有可能是正确情况下返回的数据
            //TODO 需要考虑返回值的类型
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    @Override
    public Map<Object, Object> hGetAll(String key) {
        if(StringUtils.isEmpty(key)){
            return null;
        }

        return redisTemplate.opsForHash().entries(key);
    }

    @Override
    public void hSet(String key, String field, String value) {

        if(StringUtils.isEmpty(key)||StringUtils.isEmpty(field)||StringUtils.isEmpty(value)){

        }
        redisTemplate.opsForHash().put(key, field, value);
    }

    /*
  */
    @Override
    public void HSet(String key, Map map) {

        if(StringUtils.isEmpty(key)||map==null){
            return;
        }
        redisTemplate.opsForHash().putAll(key, map);
    }

    @Override
    public String HGet(String key, String field) {

        if(StringUtils.isEmpty(key)||StringUtils.isEmpty(field)){
            return null;
        }

        Object o = redisTemplate.opsForHash().get(key, field);
        return o==null?null:o.toString();
    }

    @Override
    public Long hIncr(String key, String field, Long delta) {
        if(StringUtils.isEmpty(key)||StringUtils.isEmpty(field)){
            return 0L;
        }
        return   redisTemplate.opsForHash().increment(key, field, delta);

    }

    @Override
    public List<Object> pipelineOps(Map<String, Object> map) {
        if(map==null){
            return null;
        }

         redisTemplate.opsForValue().multiSet(map);
/*        return redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
//               打开通道
               redisConnection.openPipeline();
               map.forEach((key, Value)->{
                   redisConnection.set(key.getBytes(StandardCharsets.UTF_8),Value.toString().getBytes(StandardCharsets.UTF_8));
               });

                return null;
            }
        });*/
        return new ArrayList<>();
    }

    @Override
    public Long add2Set(String key, String ... members) {
        if(StringUtils.isEmpty(key)||StringUtils.isEmpty(members)){
            return null;
        }
        return  redisTemplate.opsForSet().add(key, members);
    }

    @Override
    public Set<Object> members(String key) {
        if(StringUtils.isEmpty(key)){
            return null;
        }
        return redisTemplate.opsForSet().members(key);
    }

    @Override
    public Boolean isMember(String key, String member) {
        if (StringUtils.isEmpty(key)||StringUtils.isEmpty(member)) {
            return false;
        }
        return  redisTemplate.opsForSet().isMember(key, member);
    }

    @Override
    public boolean del(String key, String mobile) {
        if (StringUtils.isEmpty(key)||StringUtils.isEmpty(mobile)) {
            return false;
        }
        redisTemplate.opsForSet().remove(key, mobile);
        return false;
    }

    @Override
    public  Set<Object>  filter(String key) {

        if(StringUtils.isEmpty(key)){
            return null;
        }
        Set<Object> members = redisTemplate.opsForSet().members(key);
        return members;

    }

    @Override
    public Long rPush(String key, String... values) {
        if(StringUtils.isEmpty(key)||StringUtils.isEmpty(values)){
            return null;
        }
        return redisTemplate.opsForList().rightPushAll(key, values);
    }

    @Override
    public List getDateFromList(String key, int start, int end) {
        if (StringUtils.isEmpty(key) || start < 0) {
            return null;
        }
        List<Object> range = redisTemplate.opsForList().range(key, start, end);
        return range;
    }

    @Override
    public Boolean add2Zset(String key, String value, double score) {
        Boolean result = redisTemplate.opsForZSet().add(key, value, score);


        return result;
    }

    @Override
    public Long getSizeByScore(String key, double min, double max) {

        if (StringUtils.isEmpty(key) || min > max) {
            return 0L;
        }
        long size = redisTemplate.opsForZSet().rangeByScore(key, min, max).size();


        return size;
    }

    @Override
    public Set<ZSetOperations.TypedTuple<Object>> getDataFromZset(String key, long start, long end) {
        //如果start<0 查询不了完整的结果,所以没有意义
        if (StringUtils.isEmpty(key) || start < 0) {
            return null;
        }
        Set<ZSetOperations.TypedTuple<Object>> typedTuples = redisTemplate.opsForZSet().rangeWithScores(key, start, end);
        return typedTuples;
    }

    @Override
    public String getByPiple(String key) {



        return null;
    }

    @Override
    public Long lremove(String key, String... values) {
        if (StringUtils.isEmpty(key)||StringUtils.isEmpty(values)) {
            return 0L;
        }
        Arrays.asList(values).forEach(value->{
            redisTemplate.opsForList().remove(key,0,values);
        });
        return 1L;
    }


}
